object rationals {
  val x = new Rational(4, 6)                      //> x  : Rational = 2/3
  x.denom                                         //> res0: Int = 6
  x.numer                                         //> res1: Int = 4

  val y = new Rational(2, 3)                      //> y  : Rational = 2/3
  val z = x.add(y)                                //> z  : Rational = 4/3

  z.neg                                           //> res2: Rational = 4/-3
  z.sub(x)                                        //> res3: Rational = 2/3
}

class Rational(x: Int, y: Int) {
  require(y != 0, "ZERO division!")
  def this(x: Int) = this(x, 1)

  private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
  private val g = gcd(x, y)

  def numer = x
  def denom = y

  def less(that: Rational) = numer * that.denom < that.numer * denom

  def max(that: Rational) = if (this.less(that)) that else this

  def add(that: Rational) =
    new Rational(numer * that.denom + that.numer * denom, denom * that.denom)

  override def toString = x / g + "/" + y / g

  def neg() = new Rational(-numer, denom)

  def sub(that: Rational) = add(that.neg)

}